package invocation;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * 动态代理    被代理类包装类
 */
public class LogInvocatonHandler  implements InvocationHandler {

  Logger log= LoggerFactory.getLogger(LogInvocatonHandler.class);
  //被代理类
  private Hello  hello=null;
  public LogInvocatonHandler(Hello hello){
    this.hello=hello;
  }

  /**
   *
   * @param proxy   代理类
   * @param method  代理对象实际调用的方法（这个方法肯定在Hello接口中有）
   * @param args    代理类的执行方法参数
   * @return
   *对代理对象的所有接口方法调用都会转发到InvocationHandler.invoke()方法，在invoke()方法里我们可以加入任何逻辑，比如修改方法参数，
   * 加入日志功能、安全检查功能等；之后我们通过某种方式执行真正的方法体，示例中通过反射调用了Hello对象的相应方法，还可以通过RPC调用远程方法。
   *
   * 注意1：对于从Object中继承的方法，JDK Proxy会把hashCode()、equals()、toString()这三个非接口方法转发给InvocationHandler，
   * 其余的Object方法则不会转发。详见JDK Proxy官方文档。如果对JDK代理后的对象类型进行深挖，可以看到如下信息：
   */

  @Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    if("sayHello".equals(method.getName())){
      log.info("You said: "+ Arrays.toString(args));
    }
    return method.invoke(hello,args);
  }
}
